<template>
  <div>
    <div class="uploadDiv2">
      <uploader
        ref="uploader"
        :options="uploadOptions"
        :autoStart="false"
        :files="files"
        @file-added="onFileAdded"
        @file-success="onFileSuccess"
        @file-progress="onFileProgress"
        @file-error="onFileError"
        class="uploader-app"
      >
        <uploader-unsupport></uploader-unsupport>
        <uploader-drop>
          <uploader-btn :attrs="attrs">上传</uploader-btn>
        </uploader-drop>
        <uploader-list></uploader-list>
      </uploader>
    </div>
  </div>
</template>

<script>
  import { merge } from "@/api/pub/bigFileUploader";
  import { checkResources } from "@/api/pub/resources";
  import { getToken } from "@/utils/auth";
  import SparkMD5 from "spark-md5";
  const CHUNKSIZE = 10 * 1024 * 1024;
  export default {
    name: "uploaderXk",
    props: {
      resourcesClass: {
        type: Object,
        default: null,
      }
    },
    data() {
      return {
        files: [],
        uploadOptions: {
          target: process.env.VUE_APP_BASE_API + "/plus/bigFileUpload/chunk",
          chunkSize: CHUNKSIZE,
          testChunks: true,
          checkChunkUploadedByResponse: function(chunk, message) {
            let objMessage = JSON.parse(message);
            let chunkNumbers = objMessage.chunkNumbers;
            return (chunkNumbers || []).indexOf(chunk.offset + 1) >= 0;
          },
          headers: {
            Authorization: "Bearer " + getToken()
          },
          statusText: {
            success: "成功",
            error: "出错了",
            uploading: "上传中",
            paused: "暂停中",
            waiting: "等待中"
          },
          query() {}
        },
        attrs: {
          //accept: ["video/mp4", "audio/mpeg"]
        },
        panelShow: false, //选择文件后，展示上传panel
        collapse: false
      };
    },
    computed: {
      //Uploader实例
      uploader() {
        return this.$refs.uploader.uploader;
      }
    },
    methods: {
      onFileAdded(file) {
        //console.log('resourcesClass',this.resourcesClass,file);
        let filePath = this.resourcesClass.dirPath +"/" + file.name;
        file.pause();//暂停文件
        this.computeMD5(file);
        checkResources({'filePath':filePath}).then(response => {
          //console.log(response);
          if(response.data === true){
            this.$modal.confirm('文件路径重复,是否替换文件? ').then(function() {
              file.resume(); //继续文件上传
            }).catch(() => {});
          }else{
            file.resume(); //继续文件上传
          }
        });
      },
      onFileProgress(rootFile, file, chunk) {
        //console.log('onFileProgress',chunk);
      },
      onFileSuccess(rootFile, file, response, chunk) {
        //console.log('onFileSuccess-1',file,response);
        let filePath = this.resourcesClass.dirPath +"/" + file.name;
        const resData = {name:file.name ,resourcesClassId:this.resourcesClass.id, dirPath:this.resourcesClass.dirPath, filePath:filePath, fileType:file.fileType, fileSize:file.size};
        const formData = new FormData();
        formData.append("identifier", file.uniqueIdentifier);
        formData.append("filename", file.name);
        formData.append("dirPath", this.resourcesClass.dirPath);
        formData.append("fileType", file.fileType);
        merge(formData).then(response => {
          //console.log('merge-response2',response);
          if(response.data){
            resData.fileUrl = response.data;
            this.$emit("uploadSuccess", resData);
          }
        });
      },

      onFileError(rootFile, file, response, chunk) {
        this.$message({
          message: response,
          type: "error"
        });
      },

      /**
       * 计算md5，实现断点续传及秒传
       * @param file
       */
      computeMD5(file) {
        //console.log("file", file);
        //console.log("getRoot", file.getRoot());
        let fileReader = new FileReader();
        let time = new Date().getTime();
        let blobSlice =
          File.prototype.slice ||
          File.prototype.mozSlice ||
          File.prototype.webkitSlice;
        let currentChunk = 0;
        const chunkSize = CHUNKSIZE; // 10 * 1024 * 1000;
        let chunks = Math.ceil(file.size / chunkSize); // 总块数

        let spark = new SparkMD5.ArrayBuffer();
        //由于计算整个文件的Md5太慢，因此采用只计算第1块文件的md5的方式
        let chunkNumberMD5 = 1;

        file.pause();//先暂停文件
        loadNext();

        fileReader.onload = e => {
          spark.append(e.target.result);

          if (currentChunk < chunkNumberMD5) {
            loadNext();
          } else {
            let md5 = spark.end();
            this.computeMD5Success(md5, file);
            //console.log( `MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${ file.size} 用时：${new Date().getTime() - time} ms`);
          }
        };

        fileReader.onerror = function() {
           this.$message({
              message: `文件${file.name}读取出错，请检查该文件`,
              type: "error"
            });
          file.cancel();
        };

        function loadNext() {
          //console.log("loadNext");
          let start = currentChunk * chunkSize;
          let end =
            start + chunkSize >= file.size ? file.size : start + chunkSize;

          fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
          currentChunk++;
          //console.log("计算第" + currentChunk + "块");
        }
      },

      computeMD5Success(md5, file) {
        // 将自定义参数直接加载uploader实例的opts上
        Object.assign(this.uploader.opts, {
          query: {
            ...this.params
          }
        });

        file.uniqueIdentifier = md5; //MD5处理唯一标识赋值
        //file.resume(); //继续文件上传
      }
    }
  };
</script>
